package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/errors"
	"manager/model"
	"manager/model/entity"
)

var UpgradeRecord = &upgradeRecord{}

type upgradeRecord struct{}

// Create 创建
func (a *upgradeRecord) Create(ctx context.Context, m *entity.UpgradeRecord) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find 查找详情
func (a *upgradeRecord) Find(ctx context.Context, in *model.UpgradeRecordInfoRequest) (*entity.UpgradeRecord, error) {
	e := &entity.UpgradeRecord{}

	q := GetDB(ctx).Model(&entity.UpgradeRecord{})

	if in.Id > 0 {
		err := q.First(&e, in.Id).Error
		return e, err
	}

	count := 0

	if in.FirmwareId != nil {

		q = q.Where("firmware_id = ?", in.FirmwareId)

		count++
	}

	if in.FirmwaresName != nil {

		q = q.Where("firmwares_name like ?", in.FirmwaresName)

		count++
	}

	if in.Version != nil {

		q = q.Where("version like ?", in.Version)

		count++
	}

	if in.TacticsId != nil {

		q = q.Where("tactics_id = ?", in.TacticsId)

		count++
	}

	if in.SnCode != nil {

		q = q.Where("sn_code like ?", in.SnCode)

		count++
	}

	if in.Status != nil {

		q = q.Where("status = ?", in.Status)

		count++
	}

	if in.Desc != nil {

		q = q.Where("desc like ?", in.Desc)

		count++
	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

		count++
	}

	if count == 0 {
		return e, errors.New("condition illegal")
	}

	err := q.First(&e).Error
	return e, err
}

// Update 更新
func (a *upgradeRecord) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return GetDB(ctx).Model(&entity.UpgradeRecord{}).Where("id = ?", id).Updates(dict).Error
}

// Delete 删除
func (a *upgradeRecord) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.UpgradeRecord{}, id).Error
}

// DeleteByTacticsId 删除
func (a *upgradeRecord) DeleteByTacticsId(ctx context.Context, tacticsId int64) error {
	return GetDB(ctx).Delete(&entity.UpgradeRecord{}, "tactics_id=?", tacticsId).Error
}

// FindByTacticsId 列表查询
func (a *upgradeRecord) FindByTacticsId(ctx context.Context, tacticsId int64) ([]*entity.UpgradeRecord, error) {
	var (
		q              = GetDB(ctx).Model(&entity.UpgradeRecord{})
		err            error
		upgradeRecords []*entity.UpgradeRecord
	)
	if err = q.Where("tactics_id = ?", tacticsId).Find(&upgradeRecords).Error; err != nil {
		return nil, err
	}
	return upgradeRecords, nil
}

func (a *upgradeRecord) CheckExistActivePlanBySnCode(code []string) (int64, error) {
	var (
		err error
		id  int64
	)
	sqlStr := "SELECT ft.id " +
		"FROM FIRMWARES_TACTICS FT " +
		"JOIN UPGRADE_RECORDS UR ON FT.ID = UR.TACTICS_ID " +
		"WHERE FT.STATUS != 2 " +
		"and ur.sn_code in (?) limit 1"
	err = db.Raw(sqlStr, code).Find(&id).Error
	return id, err
}

func (a *upgradeRecord) CheckExistActivePlanByTypeId(typeIds []int64) (int64, error) {
	var (
		err error
		id  int64
	)
	sqlStr := "SELECT ft.id " +
		"FROM FIRMWARES_TACTICS FT " +
		"JOIN UPGRADE_RECORDS UR ON FT.ID = UR.TACTICS_ID " +
		"JOIN ebikes eb on ur.sn_code=eb.sn_code " +
		"WHERE FT.STATUS != 2 " +
		"and type_id in (?) limit 1"
	err = db.Raw(sqlStr, typeIds).Find(&id).Error
	return id, err
}

// List 列表查询
func (a *upgradeRecord) List(ctx context.Context, in *model.UpgradeRecordListRequest) (int, []*entity.UpgradeRecord, error) {
	var (
		q              = GetDB(ctx).Model(&entity.UpgradeRecord{})
		err            error
		total          int64
		upgradeRecords []*entity.UpgradeRecord
	)

	if in.FirmwareId != nil {

		q = q.Where("firmware_id = ?", in.FirmwareId)

	}

	if in.FirmwaresName != nil {

		q = q.Where("firmwares_name like ?", in.FirmwaresName)

	}

	if in.Version != nil {

		q = q.Where("version like ?", in.Version)

	}

	if in.TacticsId != nil {

		q = q.Where("tactics_id = ?", in.TacticsId)

	}

	if in.SnCode != nil {

		q = q.Where("sn_code like ?", in.SnCode)

	}

	if in.Status != nil {

		q = q.Where("status = ?", in.Status)

	}

	if in.Desc != nil {

		q = q.Where("desc like ?", in.Desc)

	}

	if in.UpdatedAt != nil {

		q = q.Where("updated_at = ?", in.UpdatedAt)

	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&upgradeRecords).Error; err != nil {
		return 0, nil, err
	}
	return int(total), upgradeRecords, nil
}

// ExecTransaction db事务执行
func (a *upgradeRecord) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, DBCONTEXTKEY, tx)
		return callback(ctx)
	})
}
